﻿using CQIE.JonJack.Models;
using CQIE.JonJack.Models.Tabels;
using CQIE.JonJack.UtilitySource;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace CQIE.JonJack.MQList.IOServices
{
    public class PublicService
    {
        //数据库操作对象
        private readonly _DbContext _Db;
        private readonly IOptionsSnapshot<JWTSettings> jwtSettingsOpt;

        public PublicService(_DbContext db, IOptionsSnapshot<JWTSettings> jwtSettingsOpt)
        {
            _Db = db;
            this.jwtSettingsOpt = jwtSettingsOpt;
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="schoolNumber"></param>
        /// <param name="passWord"></param>
        /// <returns></returns>
         public string userLogin(string schoolNumber, string passWord)
        {

            string jwtResult = "";
            //进行登录比对
            User? user = _Db.User.Where(u => u.SchoolNumber == schoolNumber && u.PassWord == passWord).Include(u=>u.RoleId)
                                .SingleOrDefault();
            if (user != null)
            {
                //签发JWT登录证书
                //登录成功生成token
                List<Claim> claims = new();
                claims.Add(new Claim(ClaimTypes.NameIdentifier, user.SchoolNumber));//token中添加用户ID信息
                                                                 //JWT的传输中不建议设置太多东西，不然耗费流量

                //接下来正式生成token
                string key = jwtSettingsOpt.Value.SecKey;//通过依赖注入获取密钥
                DateTime expire = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSecond);//获取过期时间
                byte[] secBytes = Encoding.UTF8.GetBytes(key);//密钥转二进制
                var secKey = new SymmetricSecurityKey(secBytes);
                var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
                var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentials);
                jwtResult = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);

            }
            return jwtResult+user.RoleId.ToString();
        }
    
        public void BorrowBook(string bookId, string endTime, string schoolNumber)
        {
            using (_DbContext Db=new _DbContext())
            {
                Book book = Db.Books.Where(b => b.Id == int.Parse(bookId)).Single();
                User user = Db.User.Where(u => u.SchoolNumber == schoolNumber).Include(u => u.BookHistorys).Include(u => u.BorrowRecords)
                    .Single();

                if (user.BookHistorys.Where(b => b.BookId == int.Parse(bookId)).SingleOrDefault() == null)
                {
                    BorrowRecord record = new BorrowRecord();
                    record.User = new();
                    record.User = user;
                    record.Book = new();
                    record.Book = book;

                    string format = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzz '(中国标准时间)'";
                    record.ReturnTime = DateTime.ParseExact(endTime, format, CultureInfo.InvariantCulture);
                    record.BorrowTime = DateTime.Now;

                    Db.BorrowRecord.Add(record);

                    BookHistory history = new BookHistory();
                    history.User = new();
                    history.User = user;
                    history.Book = new();
                    history.Book = book;

                    history.BorrowTime = DateTime.Now;

                    Db.BookHistory.Add(history);
                }
                else
                {
                    string format = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzz '(中国标准时间)'";
                    user.BorrowRecords!.Where(b => b.BookId == int.Parse(bookId)).Single().ReturnTime
                        = DateTime.ParseExact(endTime, format, CultureInfo.InvariantCulture);
                }

                Db.SaveChanges();
            }
        }

    }
}
